<!DOCTYPE html>
<html>
<head>
    <title>Vizit</title>
    <link rel="stylesheet" href="css/style.css">
    <script src="node_modules/jquery/dist/jquery.js"></script>
    <script src="node_modules/@svgdotjs/svg.js/dist/svg.js"></script>
    <script src="node_modules/@svgdotjs/svg.draggable.js/dist/svg.draggable.js"></script>
</head>
<body>

<script>
    // 定义svg对象, 在body里面添加一个svg
    let svg = SVG().addTo('body').attr({width: 1000, height: 800});
    // marker: arrow head
    let marker = svg.marker(13, 13, function (add) {
        add.path('M2,2 L2,11 L10,6 L2,2').fill('blue').stroke({width: 1, color: 'blue'})
    }).attr({"refX": "2", "refY": "6", "orient": "auto"});
    // Set the global configs to synchronoussvg.js
    $.ajaxSetup({
        async: false
    });
    let version = Date.now();

    function createNode(container, data) {
        // 用一个group把节点边框和文本放在一起，这样可以利用group的transform来定义
        // 整个group里面所有节点的坐标位置
        let translateX = data.group.transform.translateX;
        let translateY = data.group.transform.translateY;
        let width = data.label.text.length * 8 + 10;
        let height = 28;
        let group = container.group()
            .transform({translateX: translateX, translateY: translateY})
            .id(data.group.id)
            .data('leftTopX', translateX)
            .data('leftTopY', translateY)
            .data('width', width)
            .data('height', height)
        ;
        // TODO style 的信息暂时hardcode, 后面会用程序控制动态变化的效果。
        let style = {fill: 'none', stroke: 'blue'};
        let attributes = {...style, ...data.shape.attributes};
        // 动态的调用函数，可以支持绘制各种图形，比如:rect, ellipse
        let rect = container[data.shape.type](width, height).attr(attributes);
        group.add(rect);

        let label = container.text(data.label.text);
        label.attr(data.label.attributes);
        group.add(label);

        return group.draggable(); // 支持拖拽
    }

    function buildPathId(path) {
        let start = path.start;
        let end = path.end;
        return `${start}_${end}`;
    }

    function createPath(container, path, marker) {
        let start = path.start;
        let end = path.end;
        let startNode = svg.findOne(`#${start}`);
        let endNode = svg.findOne(`#${end}`);
        let startX = startNode.data('leftTopX') + startNode.data('width') + path.startOffsetX;
        let startY = startNode.data('leftTopY') + startNode.data('height') + path.startOffsetY;
        let endX = endNode.data('leftTopX') + path.endOffsetX;
        let endY = endNode.data('leftTopY') + path.endOffsetY;
        let data = `M ${startX}, ${startY} L ${endX}, ${endY}`;
        let id = buildPathId(path);
        let result = container.path(data).id(id)
            .fill('blue')
            .stroke({width: 1, color: 'blue'})
            .marker('end', marker)
            .data('points', [startX, startY, endX, endY]);
        return result;
    }

    function animate(path) {
        let id = buildPathId(path);
        let points = svg.findOne(`#${id}`).data('points');
        return svg.circle(20).attr({cx: points[0], cy: points[1]}).fill('green')
            .id('circle-' + id)
            .animate(2500, 100, 'now')
            .move(points[2] - 10, points[3] - 10)
            .loop(Number.MAX_SAFE_INTEGER, false, 200)
            // .loop(1, false, 200)
            ;
    }

    SVG.on(document, 'DOMContentLoaded', function () {
        $.getJSON("data/zookeeper.json?" + version, function (data) {
            data.forEach(node => createNode(svg, node))
        });

        $.getJSON("data/brokers.json?" + version, function (data) {
            data.forEach(node => createNode(svg, node))
        });

        $.getJSON("data/paths.json?" + version, function (data) {
            data.forEach(value => createPath(svg, value, marker));
        });

        $.getJSON("data/paths.json?" + version, function (data) {
            data.forEach(value => animate(value));
        });

        $("svg").find("g").attr("display", "none");
        $("svg").find("path").attr("display", "none");
        $("svg").find("circle").attr("display", "none");

        $("#circle-broker2_zookeeper").attr("fill", "pink");
        $("#circle-zookeeper_brokers-ids-2").attr("fill", "pink");

        $("#circle-broker3_zookeeper").attr("fill", "red");
        $("#circle-zookeeper_brokers-ids-3").attr("fill", "red");

        // ['zookeeper',
        //     'broker1', 'broker1_zookeeper', 'circle-broker1_zookeeper', 'brokers-ids-1', 'zookeeper_brokers-ids-1', 'circle-zookeeper_brokers-ids-1',
        //     'controller', 'zookeeper_controller', 'circle-zookeeper_controller',
        //     'broker2', 'broker2_zookeeper', 'circle-broker2_zookeeper', 'brokers-ids-2', 'zookeeper_brokers-ids-2', 'circle-zookeeper_brokers-ids-2',
        //     'broker3', 'broker3_zookeeper', 'circle-broker3_zookeeper', 'brokers-ids-3', 'zookeeper_brokers-ids-3', 'circle-zookeeper_brokers-ids-3'
        // ]
        //     .forEach(function (value, index) {
        //         setTimeout(
        //             function () {
        //                 $("#" + value).removeAttr("display");
        //             }, 800 * index);
        //     });
        //
        // setTimeout(
        //     function () {
        //         ['broker1', 'broker1_zookeeper', 'circle-broker1_zookeeper']
        //             .forEach(function (value, index) {
        //                 $("#" + value).attr("display", "none");
        //             });
        //     }, 20000);
        //
        // setTimeout(
        //     function () {
        //         ['brokers-ids-1', 'zookeeper_brokers-ids-1', 'circle-zookeeper_brokers-ids-1']
        //             .forEach(function (value, index) {
        //                 $("#" + value).attr("display", "none");
        //             });
        //         $("#circle-zookeeper_controller").attr("fill", "pink");
        //         $('#controller').find('tspan').html('/controller (broker1)')
        //     }, 22000);

        let show_flow = ['zookeeper',
            'broker1', 'broker1_zookeeper', 'circle-broker1_zookeeper', 'brokers-ids-1', 'zookeeper_brokers-ids-1', 'circle-zookeeper_brokers-ids-1',
            'controller', 'zookeeper_controller', 'circle-zookeeper_controller',
            'broker2', 'broker2_zookeeper', 'circle-broker2_zookeeper', 'brokers-ids-2', 'zookeeper_brokers-ids-2', 'circle-zookeeper_brokers-ids-2',
            'broker3', 'broker3_zookeeper', 'circle-broker3_zookeeper', 'brokers-ids-3', 'zookeeper_brokers-ids-3', 'circle-zookeeper_brokers-ids-3'
        ].concat(['broker1', 'broker1_zookeeper', 'circle-broker1_zookeeper'])
            .concat(['brokers-ids-1', 'zookeeper_brokers-ids-1', 'circle-zookeeper_brokers-ids-1']);
        let next = 0;
        $("#show_next").click(function () {
            let id = show_flow[next++];
            console.log(id);
            $("#" + id).removeAttr("display");
        });


        $("#hide_broker0").click(function () {
            ['broker1', 'broker1_zookeeper', 'circle-broker1_zookeeper']
                .forEach(function (value, index) {
                    $("#" + value).attr("display", "none");
                });
        });

        $("#hide_brokerid0").click(function () {
            ['brokers-ids-1', 'zookeeper_brokers-ids-1', 'circle-zookeeper_brokers-ids-1']
                .forEach(function (value, index) {
                    $("#" + value).attr("display", "none");
                });
        });

        $("#hide_controller").click(function () {
            ['controller', 'zookeeper_controller', 'circle-zookeeper_controller']
                .forEach(function (value, index) {
                    $("#" + value).attr("display", "none");
                });
        });

        $("#change_controller").click(function () {
            ['controller', 'zookeeper_controller', 'circle-zookeeper_controller']
                .forEach(function (value, index) {
                    $("#" + value).removeAttr("display");
                });
            $("#circle-zookeeper_controller").attr("fill", "pink");
            $('#controller').find('tspan').html('/controller (broker1)')
        });

        $("#show_all").click(function () {
            $("svg").find("g").removeAttr("display");
            $("svg").find("path").removeAttr("display");
            $("svg").find("circle").removeAttr("display");

        });

        setTimeout(() => {
            $("svg").find("g").removeAttr("display");
            $("svg").find("path").removeAttr("display");
            $("svg").find("circle").removeAttr("display");
        }, 1000);

    })
</script>

</body>
</html>